

package club.banyuan.blog.config;

import club.banyuan.blog.common.CommonResult;
import club.banyuan.blog.config.security.CustomLoginFilter;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.PrintWriter;

@Configuration
public class StudyRoomSecurityConfig extends WebSecurityConfigurerAdapter {

    private final static String LOGIN_PAGE_URI = "/login2";
    private final static String FORBIDDEN_PAGE_URI = "/forbidden";

    @Autowired
    DataSource dataSource;

//    @Autowired
//    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 增加自定义的UserDetailService
        // userDetailsAuthenticationProvider.setUserDetailsService(userDetailsService);
        // 设置一个Provider
        //auth.authenticationProvider(userDetailsAuthenticationProvider);
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        String[] allowList = {
                "/actuator/**",
                "/static/**",
                "/**.js",
                "/**.css",
                "/**.jpg",
                "/**.jpeg",
                "/**.png",
                "/**.gif",
                "/studyroom/**",
                "/api/user/weather",
                "/api/user/login",
                "/api/user/lgout",
                "/api/user/current"
        };

        http.authorizeRequests()//开启登录配置
                .antMatchers("/api/admin/**").hasAuthority("ROLE_ADMIN")
//                .antMatchers("/api/**").hasRole("ROLE_USER")
                .antMatchers(allowList).permitAll()
                .anyRequest().authenticated() // 其他接口，登录之后就能访问

                .and()
                .formLogin()

                .and()
                .httpBasic()
                .and()
                .csrf().disable()

                // 异常
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler() {
                    @Override
                    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
                        if (httpServletRequest.getRequestURI().contains("/api/")) {
                            // 是接口
                            response.setHeader("Access-Control-Allow-Origin", "*");
                            response.setHeader("Cache-Control", "no-cache");
                            response.setCharacterEncoding("UTF-8");
                            response.setContentType("application/json");
                            response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
                            response.getWriter().flush();
                        } else {
                            // 是页面
                            response.sendRedirect(FORBIDDEN_PAGE_URI);
                        }
                    }
                })
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    @Override
                    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                        if (httpServletRequest.getRequestURI().contains("/api/")) {
                            // 是接口
                            response.setHeader("Access-Control-Allow-Origin", "*");
                            response.setHeader("Cache-Control", "no-cache");
                            response.setCharacterEncoding("UTF-8");
                            response.setContentType("application/json");
                            response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(e.getMessage())));
                            response.getWriter().flush();
                        } else {
                            // 是页面
                            response.sendRedirect(LOGIN_PAGE_URI);
                        }
                    }
                });
    }
}